unlightfandomcom_ko-20200215-history
모듈:BirthdayAlarm
-- 생일 알리미 | Birthday Alarm -- -- @Author(s): User:Cafeinlove -- @License: MIT License ------------------------------------------------------------ local p = {} local data = mw.loadData('Module:BirthdayAlarm/Data') local birthData, _birthData = data.calendar, {} -- 생일 데이터 local showLength = data.showlength -- 생일을 보여줄 기간 local now, nowMonth, nowDay, nowIndex --- processData() : 생일 데이터를 액세스하기 편리도록 재정리 local function processData() local monNum, dayNum -- parseNum() : 문자열에서 숫자를 추출 local function parseNum(str) local nStr = string.match(str, '(%d+)') if not nStr then return false else return tonumber(nStr) end end -- 3d 테이블 `birthData` => 2d 테이블 `_birthData` for month, monthVal in pairs(birthData) do monNum = parseNum(month) for day, dayVal in pairs(monthVal) do dayNum = parseNum(day) table.insert(_birthData, { index = p.getDayIndex(monNum, dayNum), value = dayVal }) end end -- _birthData 테이블을 날짜순 정렬 table.sort(_birthData, function(a, b) return a.index < b.index end) end -- setList() : 생일 목록을 생성 local function setList() local ul local curIndex = nowIndex ul = mw.html.create('ul') :attr('id', 'birthdayList') :addClass('birthday-list') -- setListItem() : 생일 목록의 각 항목 생성 local function setListItem(ul, dayIndex) local className, wText, day, repDay, daysGap local chars local charTbl = {} local charExists = false local isToday = dayIndex nowIndex for i = 1, #_birthData do if (_birthDatai.index dayIndex) then charExists = true chars = _birthDatai.value break end end if isToday false and charExists false then return end day = p.getDayStr(dayIndex) repDay = p.getRepDate(dayIndex) if isToday false then className = 'birthday-list__item' daysGap = dayIndex - nowIndex wText = (daysGap 1 and '내일' or (daysGap 2 and '모레' or daysGap .. '일 뒤')) else className = 'birthday-list__item active' wText = '오늘' end wText = wText .. ', ' ..repDay..'' .. '(' ..day..')' .. '은 ' if chars then for _, v in pairs(chars) do table.insert(charTbl, '파일:' ..v.. '_도트.gif' ..v.. '' ) end wText = wText .. table.concat(charTbl, ', ') .. '의 생일입니다.' if isToday then wText = wText .. ' 축하합니다!' end else wText = wText .. '생일을 맞은 캐릭터가 없습니다.' end ul:tag('li') :addClass(className) :wikitext(wText) end -- 보여줄 일수가 지정되지 않았거나 규격에 맞지 않으면 30일로 설정 if (not showLength) or (showLength < 1) or (showLength > 365) then showLength = 30 end -- 보여줄 일수 안에 존재하는 생일 목록을 추가 for i = 1, showLength do setListItem(ul, curIndex) if (curIndex - 365) < 0 then curIndex = curIndex + 1 else curIndex = curIndex - 364 end end return ul end --- p.getDayIndex() : 입력된 월, 일의 대응하는 날짜 인덱스값을 반환 -- 윤년은 계산되지 않음. 2월 29일은 3월 1일과 같이 60을 반환. function p.getDayIndex(month, day) local monthLength = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} local index = 0 index = index + day if month > 1 then for i = 1, month-1 do index = index + monthLengthi end end return index end --- p.getDayStr() : 입력된 날짜 인덱스값에 대응하는 월, 일을 반환 -- 윤년은 계산되지 않음 function p.getDayStr(index) local monthLength = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} local tbl = {} local month = 1 for i = 1, #monthLength do if (index - monthLengthi > 0) then index = index - monthLengthi month = i + 1 end end tbl1 = month .. '월' tbl2 = index .. '일' return table.concat(tbl, ' ') end --- p.getRepDate() : 날짜 인덱스값으로 혁명력 날짜를 구함 function p.getRepDate(dayIndex) local rMonths = { {'눈의 달', 30}, {'비의 달', 30}, {'바람의 달', 30}, {'새싹의 달', 30}, {'꽃의 달', 30}, {'목초의 달', 30}, {'수확의 달', 30}, {'열의 달', 30}, {'열매의 달', 30}, {'축제', 5}, {'포도의 달', 30}, {'안개의 달', 30}, {'서리의 달', 30} } local index = dayIndex local i = 1 local repDate = {} -- 눈의 달 12일부터 시작 index = index + 11 -- 달력을 넘겨 현재 날짜까지 이동 while(index - rMonthsi2 > 0) do index = index - rMonthsi2 if i < #rMonths then i = i + 1 else i = 1 end end -- 알맞은 날짜 이름을 골라 반환 repDate1 = rMonthsi1 repDate2 = index .. '일' return table.concat(repDate, ' ') end function p.main(frame) local output -- 현재 월, 일을 파악해 변수에 저장 now = os.date('*t', os.time()+32400) -- GMT+9 nowMonth, nowDay = now.month, now.day nowIndex = p.getDayIndex(nowMonth, nowDay) -- 데이터를 재정렬 processData() -- 출력을 구축 output = setList() return output:done() end return p